package com.irdstudio.biz.drools.common;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期时间工具
 */
public class RuleUtil {

    private static Logger log = LoggerFactory.getLogger(RuleUtil.class);

    /**
     * 系统默认日期格式
     */
    public static final String DEFAULT_FORMAT_PATTERN = "yyyy-MM-dd HH:mm:ss";
    /**
     * 系统默认日期格式
     */
    public static final String DEFAULT_FORMAT_PATTERN_YYYY_MM_DD = "yyyy-MM-dd";

    /**
     * 字符串转换Date
     * @param time
     * @param pattern
     * @return
     */
    public static Date parse(String time, String pattern) {
        try {
            Date date = DateUtils.parseDate(time, pattern, DEFAULT_FORMAT_PATTERN, DEFAULT_FORMAT_PATTERN_YYYY_MM_DD);
            return date;
        } catch (Exception e) {
            //ignore
            return null;
        }
    }

    public static Date parse(String time) {
        return parse(time, DEFAULT_FORMAT_PATTERN);
    }

    /**
     * 将Date转换成指定模式的字符串
     * @param time
     * @param pattern
     * @return
     */
    public static String parseToString(Date time, String pattern) {
        return DateFormatUtils.format(time, pattern);
    }

    public static String parseToString(Date time) {
        return parseToString(time, DEFAULT_FORMAT_PATTERN);
    }

    public static String now() {
        return parseToString(new Date());
    }

    /**
     * 判断两个日期相差是否少于 val
     * @param one
     * @param two
     * @param val
     * @param calendarType Calendar
     * @return
     */
    public static Integer compareDate(String one, String two, String val, int calendarType) {
        Date oneDate = parse(one);
        Date twoDate = parse(two);
        if (oneDate == null && twoDate == null) {
            return 0;
        }
        if (oneDate == null || twoDate == null) {
            return -1;
        }
        // 防止空指针
        if (val == null) {
            val = "0";
        }
        Calendar twoCal = Calendar.getInstance();
        twoCal.setTime(twoDate);
        twoCal.add(calendarType, Integer.valueOf(val));
        Date plusTwo = twoCal.getTime();
        return oneDate.compareTo(plusTwo);
    }

    /**
     * 判断两个日期相差是否少于years
     * one - two < years
     * @param one 日期1
     * @param two 日期2
     * @param years 年份阀值 整数
     * @return 少于years 返回-1, 等于返回0 大于返回 1
     */
    public static Integer compareYears(String one, String two, String years ) {
        return compareDate(one, two, years, Calendar.YEAR);
    }

    /**
     * 与当前时间比较
     * currentTime - time < val
     * @param time
     * @param val
     * @param calendarType
     * @return
     */
    public static Integer compareCurrentTime(String time, String val, int calendarType) {
        Date now = new Date();
        return compareDate(parseToString(now), time, val, calendarType);
    }

    /**
     * 转换数字类型为BigDecimal
     * @param num String int float double
     * @return BigDecimal
     */
    public static BigDecimal convertNumber(Object num) {
        if (num == null) {
            //throw new NullPointerException("convertNumber argument num is null");
            return BigDecimal.ZERO;
        }
        BigDecimal number = null;
        if (num instanceof BigDecimal) {
            number = (BigDecimal) num;
        } else {
            String numStr = num.toString();
            if (numStr.contains(",")) {
                numStr = numStr.replaceAll(",", "");
            }
            number = new BigDecimal(numStr);
        }
        number = number.setScale(6, BigDecimal.ROUND_HALF_UP);
        return number;
    }

    /**
     * 比较数值大小
     * @param one
     * @param two
     * @return
     */
    public static int numberCompare(Object one, Object two) {
        BigDecimal oneNum = convertNumber(one);
        BigDecimal twoNum = convertNumber(two);
        return oneNum.compareTo(twoNum);
    }

    /**
     * 字符串判断是否包含列表中的关键词
     * @param list 关键词
     * @param val 字符串
     * @return
     */
    public static Boolean strListContains(Object[] list, Object val) {
        if (list == null || list.length < 1) {
            return true;
        }
        String valStr = val.toString();
        for (Object obj : list) {
            if (obj == null) {
                continue;
            }
            String objStr = obj.toString();
            if (valStr.contains(objStr)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否为list 是返回list.size 否返回-1
     * @param listObj
     * @return 是返回list.size 否返回-1
     */
    public static int getListSize(Object listObj) {
        if (listObj == null) {
            return -1;
        }
        if (listObj instanceof List) {
            List list = (List) listObj;
            return list.size();
        } else {
            return -1;
        }
    }

    /**
     * 比较又有区间，还有列表的
            期限值	12-96（常规：12、15、18、24、36、60）
            期限值	1-12（常规：3、6、9、12）
            期限值	1-36（常规：1-12、24、36）
            期限值	1-36（常规：1-12、24、36）
            期限值	1-36（常规：1-12、24、36）
            期限值	1-60（常规：1-12、36、60）
            期限值	36
            期限值	12、60
     * @param target
     * @param min
     * @param max
     * @param set
     * @return
     */
    public static Boolean compareIntervalOrContains(Object target, Object min, Object max, Object set) {
        if (target == null) {
            return false;
        }
        boolean flag = false;
        try {
            Integer targetNum = Integer.valueOf(target.toString());
            if (set != null) {
                String setStr = set.toString();
                flag = Arrays.asList(StringUtils.split(setStr, ",")).contains(target.toString());
            }
            if (min != null && max != null && !flag) {
                Integer minNum = Integer.valueOf(min.toString());
                Integer maxNum = Integer.valueOf(max.toString());
                flag = (targetNum.compareTo(minNum) >= 0 && targetNum.compareTo(maxNum) <= 0);
            }
            return flag;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 根据身份证或者出生日期计算年龄
     * @param certCode 证件号码
     * @param certType 证件类型
     * @param birDate 出生年月日
     * @return 年龄
     */
    public static int calcAgeByDate(String certCode, String certType, String birDate) {
        Date date = null; // 最终计算日期
        if (certType != null && certType.equals("20") ) {
            // 为身份证
            String dateStr;
            if (certCode.length() == 15) {
                dateStr = "19" + certCode.substring(6, 12);
            } else if (certCode.length() == 18) {
                dateStr = certCode.substring(6, 14);
            } else {//默认是合法身份证号，但不排除有意外发生
                return -1;
            }
            Date certDate = parse(dateStr, "yyyyMMdd");
            if (certDate == null) {
                return -1;
            }
            date = certDate;
        } else {
            // 根据出生年月日来计算
            if (birDate == null) {
                return -1;
            }
            Date bir = parse(birDate, "yyyy-MM-dd");
            if (bir == null) {
                return -1;
            }
            date = bir;
        }

        Calendar calendar = Calendar.getInstance();

        int yearNow = calendar.get(Calendar.YEAR);
        int monthNow = calendar.get(Calendar.MONTH);
        int dayOfMonthNow = calendar.get(Calendar.DAY_OF_MONTH);

        calendar.setTime(date);


        int yearBirthday = calendar.get(Calendar.YEAR);
        int monthBirthday = calendar.get(Calendar.MONTH);
        int dayOfMonthBirthday = calendar.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirthday;


        if (monthNow <= monthBirthday && monthNow == monthBirthday && dayOfMonthNow < dayOfMonthBirthday || monthNow < monthBirthday) {
            age--;
        }

        return age;
    }

    public static int calcAgeByDate(Object certCode, Object certType, Object birDate){
        return calcAgeByDate(
                certCode == null ? null : certCode.toString(),
                certType == null ? null : certType.toString(),
                birDate == null ? null : birDate.toString()
        );
    }

    /**
     * drl Left Hand Side (when) syntax logging
     * @param msg
     * @param args
     * @return
     */
    public static Boolean debugLog(String msg, Object ... args) {
        if (log.isDebugEnabled()) {
            log.debug(msg, args);
        }
        return true;
    }

    /**
     * 字符串包含
     * @param str
     * @param contain
     * @return
     */
    public static Boolean strContains(Object str, Object contain) {
        if (str == null || contain == null) {
            return false;
        }
        String[] contains = StringUtils.split(contain.toString(), ",");
        log.debug("********************* {}| {}", str, contain);
        for (String c : contains) {
            boolean flag = StringUtils.contains(str.toString(), c);
            if (flag) {
                return flag;
            }
        }
        return false;
    }
}
